<script setup lang='ts'>
import type { VxeGridProps } from 'vxe-table'

import { useGetCalculateResult, useGetCalculationItemOptions } from '@fl/api/purchase'
import { SearchTable } from '@fl/components'
import SubmitBtn from '@fl/components/submit-btn.vue'
import { cloneDeep, debounce } from 'lodash-es'

import { CALCULATION_TYPE } from './constant'

const props = defineProps<{
    formulaData: any
}>()
const emit = defineEmits<{
    save: [params: any, result: number, step: number]
}>()
const visible = defineModel<boolean>('visible', { required: true })
const dialogTitle = '计算公式'

const calculationItemsData = ref<any[]>([])

const getCalculationItemOptionsParams = computed(() => (props.formulaData?.varData || [])
    .filter((item: any) => item.calculationType === CALCULATION_TYPE.SELECT)
    .map((item: any) => item.calculationCategoryId))
const getCalculateResultParams = computed(() => ({
    formula: props.formulaData?.formula,
    varParams: cloneDeep(calculationItemsData.value),
}))

const {
    data: calculationItemOptionsData,
    isLoading: _isGetCalculationItemOptionsLoading,
    refetch: refetchCalculationItemOptions,
} = useGetCalculationItemOptions(getCalculationItemOptionsParams)
const {
    data: calculateResultData,
    isLoading: _isGetCalculateResultLoading,
    refetch: refetchCalculateResult,
} = useGetCalculateResult(getCalculateResultParams)

// #region Form
const formRef = ref()
const isSubmitLoading = computed(() => false)
// #endregion

// #region Table
const isFormulaTableLoading = computed(() => false)
const formulaTableData = ref<any[]>([])

const formulaGridOptions = reactive<VxeGridProps>({
    align: 'left',
    border: 'inner',
    columns: [
        { field: 'formula', title: '计算公式' },
        { field: 'formulaResult', slots: { default: 'formula_result' }, title: '计算结果' },
    ],
    headerRowClassName: 'bg-white text-[#86909C] text-[14px]',
    height: undefined,
})
// #endregion

// #region UI Listener
function onSaveBtnClick() {
    const result = calculateResultData.value
    if (result === undefined) {
        ElMessage.warning('请先计算出结果')
    }
    else {
        emit('save', getCalculateResultParams.value, calculateResultData.value, props.formulaData.step)
        cancel()
    }
}

function cancel() {
    visible.value = false
}

function closed() {
    formRef.value.formInstance?.resetFields()
    calculationItemsData.value = []
}

function opened() {
    calculationItemsData.value = cloneDeep(props.formulaData?.varData) || []
    refetchCalculationItemOptions()
}

function onCalculationItemCategoryDataIdChange(value: any, row: any) {
    row.varValue = calculationItemOptionsData.value?.[row.calculationCategoryId].find((item: any) => item.calCategoryDataId === value).value
}
// #endregion

watch(() => getCalculateResultParams.value.varParams, debounce((newValue) => {
    if (newValue && newValue.length > 0 && newValue.every((item: any) =>
        !['', null, undefined].includes(item.varValue) && !Number.isNaN(Number.parseFloat(item.varValue)))) {
        refetchCalculateResult()
    }
}, 500))

watchEffect(() => {
    formulaTableData.value = [{
        formula: props.formulaData?.formula,
        formulaResult: Number.isNaN(Number.parseFloat(calculateResultData.value)) ? '-' : calculateResultData.value,
    }]
})
</script>

<template>
    <PlusDialog v-model="visible"
                :title="dialogTitle"
                width="800"
                close-on-press-escape
                @cancel="cancel"
                @closed="closed"
                @opened="opened"
    >
        <el-form ref="formRef"
                 label-width="auto"
        >
            <el-row>
                <el-col :span="24"
                        class="mt-20"
                >
                    <span class="text-[16px] font-semibold">计算项</span>
                </el-col>

                <el-col :span="24">
                    <el-row :gutter="50">
                        <el-col v-for="item in calculationItemsData"
                                :key="item.varName"
                                :span="12"
                        >
                            <el-row>
                                <el-col :span="24"
                                        class="mt-20"
                                >
                                    <span>{{ item.varName }}</span>
                                </el-col>

                                <el-col :span="24"
                                        class="mt-8"
                                >
                                    <el-form-item>
                                        <el-input v-if="[CALCULATION_TYPE.TEXT_INPUT, CALCULATION_TYPE.RESULT].includes(item.calculationType)"
                                                  v-model="item.varValue"
                                                  :placeholder="item.calculationType === CALCULATION_TYPE.RESULT ? '请计算' : '请输入'"
                                                  clearable
                                                  class="flex-1"
                                                  type="number"
                                                  :disabled="item.calculationType === CALCULATION_TYPE.RESULT"
                                        />

                                        <el-select v-else-if="item.calculationType === CALCULATION_TYPE.SELECT"
                                                   v-model="item.calCategoryDataId"
                                                   placeholder="请选择"
                                                   class="flex-1"
                                                   @change="onCalculationItemCategoryDataIdChange($event, item)"
                                        >
                                            <el-option v-for="option in (calculationItemOptionsData?.[item.calculationCategoryId] || [])"
                                                       :key="option.calCategoryDataId"
                                                       :label="option.label"
                                                       :value="option.calCategoryDataId"
                                            />
                                        </el-select>

                                        <span class="ml-16 inline-block truncate text-left w-70">
                                            {{ item.unitName && item.unitType ? `${item.unitName}(${item.unitType})` : '' }}
                                        </span>
                                    </el-form-item>
                                </el-col>
                            </el-row>
                        </el-col>
                    </el-row>
                </el-col>

                <el-col :span="24"
                        class="mt-50"
                >
                    <span class="text-[16px] font-semibold">计算式</span>
                </el-col>

                <el-col :span="24"
                        class="mt-10"
                >
                    <div class="w-full">
                        <SearchTable v-bind="formulaGridOptions"
                                     :loading="isFormulaTableLoading"
                                     :data="formulaTableData"
                        >
                            <template #formula_result="{ row }">
                                <span class="text-[#dA0004]">{{ row.formulaResult }}</span>
                            </template>
                        </SearchTable>
                    </div>
                </el-col>
            </el-row>
        </el-form>

        <template #footer>
            <div class="mx-auto mt-40">
                <SubmitBtn type="primary"
                           :loading="isSubmitLoading"
                           @click="onSaveBtnClick"
                >
                    保存
                </SubmitBtn>

                <el-button @click="cancel">
                    取消
                </el-button>
            </div>
        </template>
    </PlusDialog>
</template>

<style scoped lang="scss">
:deep(.el-form-item--default) {
    margin-bottom: 0;
}
:deep(.vxe-table--body-wrapper) {
    min-height: 48px !important;
}
:deep(.vxe-grid--toolbar-wrapper) {
    display: none;
}
</style>
